# soundcontroller_linux.py (Ubuntu 适配版)
import numpy as np
import sounddevice as sd
import threading
import time
from pynput import keyboard

# 数字键到频率的映射
key_to_freq = {
    "7": 18500,
    "8": 18700,
    "9": 18900,
    "4": 19100,
    "6": 18600,
    "1": 18800,
    "2": 19000,
    "3": 19200,
}


class AudioPlayer:
    """音频播放管理器 (Ubuntu 适配版)"""

    def __init__(self):
        self.active_frequencies = set()
        self.lock = threading.Lock()
        self.listener = None

    def sound_creator(self, frequency, sample_rate=48000):  # 提高采样率
        """生成指定频率的正弦波"""
        duration = 0.1
        t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
        wave = np.sin(2 * np.pi * frequency * t)
        return wave.astype(np.float32)

    def audio_player(self, frequency):
        try:
            wave = self.sound_creator(frequency)
            stream = sd.OutputStream(samplerate=48000, channels=1, dtype="float32")
            with stream:
                while self.is_playing(frequency):
                    stream.write(wave)
        except Exception as e:
            print(f"音频播放错误: {str(e)}")

    def is_playing(self, frequency):
        with self.lock:
            return frequency in self.active_frequencies

    def start_playback(self, frequency):
        if not self.is_playing(frequency):
            with self.lock:
                self.active_frequencies.add(frequency)
            thread = threading.Thread(target=self.audio_player, args=(frequency,))
            thread.daemon = True
            thread.start()

    def stop_playback(self, frequency):
        if self.is_playing(frequency):
            with self.lock:
                self.active_frequencies.discard(frequency)

    def on_press(self, key):
        """按键按下事件处理"""
        try:
            key_char = key.char
            if key_char in key_to_freq:
                frequency = key_to_freq[key_char]
                self.start_playback(frequency)
        except AttributeError:
            pass

    def on_release(self, key):
        """按键释放事件处理"""
        try:
            key_char = key.char
            if key_char in key_to_freq:
                frequency = key_to_freq[key_char]
                self.stop_playback(frequency)
        except AttributeError:
            pass

    def start_key_listener(self):
        """启动键盘监听器"""
        with keyboard.Listener(
            on_press=self.on_press, on_release=self.on_release
        ) as listener:
            self.listener = listener
            listener.join()


def main():
    player = AudioPlayer()

    # 启动键盘监听线程
    key_thread = threading.Thread(target=player.start_key_listener)
    key_thread.daemon = True
    key_thread.start()

    print("按住数字键(1,2,3,4,6,7,8,9)开始发声，松开停止...")
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("\n程序已退出")
        if player.listener:
            player.listener.stop()


if __name__ == "__main__":
    main()
